// 线程安全的懒汉模式
#include <chrono>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>

class Singleton {
public:
    static Singleton* getInstance(
        const std::string& value) {  // 对外接口，通过这个获取单例
        if (instance == nullptr) {   // 实例未创建，则创建实例
            std::unique_lock<std::mutex> lock(_mutex);  // 加锁
            if (instance ==
                nullptr) {  // 双检查锁定模式，避免在多线程环境下创建多个实例
                instance = new Singleton(value);
            }
            _mutex.unlock();  // 解锁
        }
        return instance;  // 返回单例对象
    }

    std::string value() const { return _value; }

protected:
    std::string _value;
    static Singleton* instance;  // 单例为静态成员变量，类内声明，类外初始化
    static std::mutex _mutex;

    void operator=(const Singleton&) =
        delete;  // 删除拷贝赋值运算符，类的用户不能对单例对象进行拷贝赋值操作
    Singleton(Singleton& other) = delete;  // 删除拷贝构造函数
    Singleton(const std::string value)     // 构造函数设为私有
        : _value(value) {}
};

Singleton* Singleton::instance = nullptr;  // 类外初始化静态变量
std::mutex Singleton::_mutex;

void ThreadFoo() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("FOO");
    std::cout << "value: " << singleton->value() << "\n";
}

void ThreadBar() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("BAR");
    std::cout << "value: " << singleton->value() << "\n";
}

int main() {
    std::thread t1(ThreadFoo);
    std::thread t2(ThreadBar);
    t1.join();
    t2.join();

    return 0;
}